#include <iostream>
#include <boost/program_options.hpp>
#include <string>
#include <math.h>
#include "get_arg.h"


// link with -lboost_filesystem-gcc -lboost_program_options-gcc
// program_options_helper.cpp

#define DEBUG_LEVEL 6
#include <debug_func.h>


// my functions
#include <print_error.h>
#include <program_options_helper.h>
using namespace BioCPP;




using std::string;
using std::cerr;
using namespace program_options_helper;
namespace po = boost::program_options_lg;


//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//	select_matrix_file_format

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

	USAGE:

                --from_regex "([^\t]+)\t"
                --to_regex "\$1\t$match\t"
                --lookup_file file
                --keep_non_matching_lines
                [--match_regex "\$1"]
                [--verbose]
				[--help]

    Iterates through files and filters each line according to the supplied
        regular expression
    The $match variable is the result of lookup what corresponds to
        --match_regex (defaults to $1) after the match
        in the --lookup_file

	Prints to STDOUT


//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{

//	char input_format;
	char output_format;

	po::options_description mandatory_args("Mandatory Arguments");
	mandatory_args.add_options()
	("regex_from,r", po::value<string>(&args.from_regex)
											->set_name("REGEX")
											->default_value("(\\S+)"),
									"Regular expression for the identifier to be substituted. "
									"Defaults to first group of non-whitespace letters.")
	("to,t", po::value<string>(&args.to_regex)
											->set_name("STRING")
											->default_value("$1"),
									"Result of substitution. $0-$9 are the results of the match."
									"$LOOKUP is the result of any lookup.");

	po::options_description optional_args("Optional Arguments");
	optional_args.add_options()
	("keep_non_matching_lines,k", "Otherwise lines not matching --regex_from REGEX will "
									"be discarded.")
	("lookup_file,l", po::value<string>(&args.file_lookup)->set_name("FILE"),
									"File containing tab delimited values which"
									"where e.g. INDICES = \"1,3,9,11-13\".")
	("wrap_line,w", po::value<unsigned>(&args.line_wrap)->default_value(60)->set_name("LENGTH"),
									"Wrap FASTA, CLUSTAL or PHYLIP lines after LENGTH characters.\1"
									"0=Do not Wrap")
	("names,n",						"STDIN will contain names of sequence to be retrieved.")
	("err_log,e", po::value<string>(&args.err_log_name)->set_name("PATH")
									->default_value("STDERR"),
									"For logging errors.")
	("alphabetic_order,a",			"Print with names sorted alphabetically")
	("verbose,v",					"Issue lots more messages.")
	("version,V",					"Print version.")
	("help,h",						"Display this message.");

	args.add_std_options();

	po::options_description all_args("");
	all_args.add(mandatory_args).add(optional_args);

	// parse command line
	po::variables_map vm;
	po::store(po::command_line_parser(argc, argv).options(all_args).run(), vm);
	po::notify(vm);

	if (vm.count("version"))
	{
		print_version(cerr, *argv, "1.0");
		return false;
	}
	if (vm.count("help"))
	{
		string exe_description =
				"Takes a sequence file and outputs it in the specified format.\n"
				"The sequences filtered to only include names matching those specified "
				"via STDIN (--names). Names are matched against the accessions using "
				"a regular expression.\n"
				"If --positions is not specified, only sequences with accessions matching "
				"REGEX will be retained.\n"
				"N.B. Duplicates are allowed. E.g. --positions \"1,1,2,2\".\n";
		print_usage(cerr, string(*argv), "\n--sequences FILE [OPTIONS]",
											all_args, exe_description, 80);
		return false;
	}
	check_required_options(vm, mandatory_args);

	args.header		= vm.count("header");
	args.names		= vm.count("names");
	args.verbose	= vm.count("verbose");
	args.alpha		= vm.count("alphabetic_order");

//	select_sequence_file_format(input_format, args.input_format, "input format");
	BioCPP::select_sequence_file_format(output_format, args.output_format, "output format");

	// check pair indices
	try
	{
		parse_indices(pos_indices_str, args.pos_indices);
	}
	catch (std::runtime_error& err)
	{
		throw std::runtime_error(string("--position INDICES incorrectly specified:\n") +
											err.what());
	}

	args.open_log_files();
	return true;
}





void t_program_args::open_log_files()
{
	debug_func_cerr( 8 );
	// make sure the error log file is valid
	if (err_log_name.length() && err_log_name != "STDERR")
	{
		f_err_log.open(err_log_name.c_str(), std::ios_base::out | std::ios_base::ate);
		if (!f_err_log.good())
			throw std::runtime_error("Could not open the error log file (" +
										err_log_name + ")");
		log_to_file		= true;
	}
	else
		log_to_file		= false;

}



